﻿#include <stdio.h>
#include "basic_io.h"
#include <string.h>
#include <stdlib.h>
#include "basic_io.h"
#include "grammar.h"
#define _CRT_SECURE_NO_WARNINGS

VARIANT memory[MEMORY_SIZE];
CODE code[PROGRAM_SIZE];

typedef enum
{
    key_input = 0,  // INPUT
    key_print,      // PRINT
    key_for,        // FOR .. TO .. STEP
    key_next,       // NEXT
    key_while,      // WHILE
    key_wend,       // WEND
    key_if,         // IF
    key_else,       // ELSE
    key_endif,      // END IF
    key_goto,       // GOTO
    key_let,        // LET
	key_break,
	key_exit
} keywords;

keywords yacc(const STRING line)
{
    if (!strnicmp(line, "INPUT ", 6))
    {
        return key_input;
    }
    else if (!strnicmp(line, "PRINT ", 6))
    {
        return key_print;
    }
    else if (!strnicmp(line, "FOR ", 4))
    {
        return key_for;
    }
    else if (!stricmp(line, "NEXT"))
    {
        return key_next;
    }
    else if (!strnicmp(line, "WHILE ", 6))
    {
        return key_while;
    }
    else if (!stricmp(line, "WEND"))
    {
        return key_wend;
    }
    else if (!strnicmp(line, "IF ", 3))
    {
        return key_if;
    }
    else if (!stricmp(line, "ELSE"))
    {
        return key_else;
    }
    else if (!stricmp(line, "END IF"))
    {
        return key_endif;
    }
    else if (!strnicmp(line, "GOTO ", 5))
    {
        return key_goto;
    }
    else if (!strnicmp(line, "LET ", 4))
    {
        return key_let;
    }
    else if (strchr(line, '='))
    {
        return key_let;
    }
	else if (!stricmp(line, "BREAK"))
	{
		return key_break;
	}
	return key_exit;//要再加一个类型
}

void (*key_func[])(const STRING) = {
    exec_input,
    exec_print,
    exec_for,
    exec_next,
    exec_while,
    exec_wend,
    exec_if,
    exec_else,
    exec_endif,
    exec_goto,
    exec_assignment,
	exec_break,
	exec_exit
};
int getnumber(const STRING line) {
    int i = 0;
    int sum = 0;
    for (i = 0; i < 4; i++) {
        
        sum = sum * 10 + (line[i] - '0');
    }
    return sum;
};
int cp0 = 1;
void readop(STRING name) {
    if ((strnicmp(code[cp].line, "IF ", 3) != 0) && (strnicmp(code[cp].line, "WHILE ", 6) != 0) && (strnicmp(code[cp].line, "FOR ", 4) != 0) && (strnicmp(code[cp].line, "GOTO ", 5) != 0)) {
        (*key_func[yacc(code[cp].line)]) (code[cp].line);
    }
    else {
        if (strnicmp(code[cp0].line, "FOR ", 4) == 0) {
            //load_program(name);
            while (strcmp(code[cp].line, "NEXT") != 0) {
                cp++;
                load_program(name);

            }
            int cp00 = cp0;
            cp0 = cp;
            cp = cp00;
            code_size = cp0;
            while (cp <= cp0)
            {
                (*key_func[yacc(code[cp].line)]) (code[cp].line);
                cp++;
            }
            cp = cp0;

        }
        if (strnicmp(code[cp0].line, "WHILE ", 6) == 0) {
            //load_program(name);
            while (strcmp(code[cp].line, "WEND") != 0) {
                cp++;
                load_program(name);

            }
            int cp00 = cp0;
            cp0 = cp;
            cp = cp00;
            code_size = cp0;
            while (cp <= cp0)
            {
                (*key_func[yacc(code[cp].line)]) (code[cp].line);
                cp++;
            }
            cp = cp0;
        }
        if (strnicmp(code[cp0].line, "IF ", 3) == 0) {
            //load_program(name);
            while (strcmp(code[cp].line, "END IF") != 0) {
                cp++;
                load_program(name);

            }
            int cp00 = cp0;
            cp0 = cp;
            cp = cp00;
            code_size = cp0;
            while (cp <= cp0)
            {
                (*key_func[yacc(code[cp].line)]) (code[cp].line);
                cp++;
            }
            cp = cp0;
        }
        if ((strnicmp(code[cp0].line, "GOTO ", 5) == 0)) {
            int gotolen = strlen(code[cp0].line);
            STRING number;
            int j = 0;
            for (int i = gotolen - 4; i < gotolen; i++)
                number[j++] = code[cp0].line[i];
            int sum = getnumber(number);
            while (code[cp].ln != sum)
            {
                cp++;
                load_program(name);
            }
            cp0 = cp;
            code_size = cp0;
            readop(name);
        }

    }

}
int main(int argc, char* argv[])
{
	STRING name;
	int user_op;//记录用户选择
    printf_s("请您选择\n 1:手动逐行读入\n 2:手动一次读入 \n 3:文件一次读入 \n");
    scanf_s("%d", &user_op);
    if (user_op==1)
    {
		printf("开始输入\n");
        while (true) {
            load_program(name);
            cp0 = cp;
            readop(name);
            cp++;

        }
    }
    if (user_op==2)
    {
		printf("请输入代码段 以END结尾\n");
        load_programinput(name);
        while (cp < code_size)
        {
            (*key_func[yacc(code[cp].line)]) (code[cp].line);
            cp++;
        }
    }
    if (user_op==3)
    {
		printf("请输入文件名：\n");
		scanf("%s", name);
        load_programtext(name);

        while (cp < code_size)
        {
            (*key_func[yacc(code[cp].line)]) (code[cp].line);
            cp++;
        }
    }
    /*
    while (cp < code_size)
    {
        (*key_func[yacc(code[cp].line)]) (code[cp].line);
        cp++;
    }
    */
    return EXIT_SUCCESS;
}